package com.luncen.index;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

import com.model.Song;
import com.spider.config.Config;

public class MusicIndex {

	private Directory directory = null;
	private static IndexReader reader = null;
	private static IndexWriter writer = null;

	public MusicIndex() {
		try {
			directory = FSDirectory.open(Config.INDEX_FILE);
			reader = IndexReader.open(directory);
			IndexWriterConfig writerConfig = new IndexWriterConfig(
					Config.VERSION, Config.ANALYZER);
			writer = new IndexWriter(directory, writerConfig);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public IndexSearcher getIndexSearcher() {
		try {
			if (reader == null) {
				reader = IndexReader.open(directory);
			} else {
				IndexReader ir = IndexReader.openIfChanged(reader);
				if (ir != null) {
					reader.close();
					reader = ir;
				}
			}
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return new IndexSearcher(reader);
	}

	public void add(Song song) {
		try {
			Document doc = null;
			doc = new Document();
			doc.add(new Field("song", song.getSong(), Store.YES, Index.ANALYZED));
			doc.add(new Field("ablum", song.getAblum(), Store.YES,
					Index.ANALYZED));
			doc.add(new Field("singer", song.getSinger(), Store.YES,
					Index.ANALYZED));
			doc.add(new Field("data", song.getData(), Store.YES,
					Index.NOT_ANALYZED));
			writer.addDocument(doc);
			writer.commit();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void delete(Song song) {
		try {
			writer.deleteDocuments(new Term("song", song.getSong()));
			writer.commit();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public List<Song> search(Query query, int num) {
		IndexSearcher searcher = getIndexSearcher();
		List<Song> songs = new ArrayList<Song>();
		try {
			TopDocs topDocs = searcher.search(query, num);
			for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
				Document d = searcher.doc(scoreDoc.doc);
				Song song = new Song();
				song.setSong(d.get("song"));
				song.setSinger(d.get("singer"));
				song.setAblum(d.get("ablum"));
				song.setData(d.get("data"));
				songs.add(song);
			}
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (searcher != null) {
					searcher.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return songs;
	}

}
